using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.Design;
using System.IO;
using System.Linq;
using PrismFactory.SoftwareFactory.Views.Properties;
using PrismGuidancePackage.Views.Services;

namespace PrismFactory.SoftwareFactory.Views.CreateSolution
{
    public class EnsurePrismAssembliesPageViewModel : ViewModelBase
    {
        public const string PrismAssembliesWpfKey = "PrismAssembliesWpf";
        public const string PrismAssembliesSilverlightKey = "PrismAssembliesSilverlight";
        public const string PrismAssembliesPathWpfKey = "PrismAssembliesPathWpf";
        public const string PrismAssembliesPathSilverlightKey = "PrismAssembliesPathSilverlight";

        private readonly IDictionaryService dictionaryService;
        private readonly IFileSystemService fileSystemService;
        private ObservableCollection<AssemblyItem> prismAssembliesWpf;
        private ObservableCollection<AssemblyItem> prismAssembliesSilverlight;

        public EnsurePrismAssembliesPageViewModel(IDictionaryService dictionaryService, IFileSystemService fileSystemService)
        {
            this.dictionaryService = dictionaryService;
            this.fileSystemService = fileSystemService;
            ValidatedProperties = new[]
                                      {
                                          PrismAssembliesPathWpfKey,
                                          PrismAssembliesPathSilverlightKey,
                                      };
        }

        public ObservableCollection<AssemblyItem> PrismAssembliesWpf
        {
            get
            {
                if (prismAssembliesWpf == null)
                {
                    prismAssembliesWpf = new ObservableCollection<AssemblyItem>();
                    FillAssembliesInfoCollection(prismAssembliesWpf, PrismAssembliesWpfKey);
                }
                return prismAssembliesWpf;
            }
        }

        public ObservableCollection<AssemblyItem> PrismAssembliesSilverlight
        {
            get
            {
                if (prismAssembliesSilverlight == null)
                {
                    prismAssembliesSilverlight = new ObservableCollection<AssemblyItem>();
                    FillAssembliesInfoCollection(prismAssembliesSilverlight, PrismAssembliesSilverlightKey);
                }
                return prismAssembliesSilverlight;
            }
        }

        public string PrismAssembliesPathWpf
        {
            get { return (string) dictionaryService.GetValue(PrismAssembliesPathWpfKey); }
            set
            {
                dictionaryService.SetValue(PrismAssembliesPathWpfKey, value);
                SetAssembliesExistenceFlag(PrismAssembliesWpf, PrismAssembliesPathWpf);
                OnPropertyChanged(PrismAssembliesPathWpfKey);
            }
        }

        public string PrismAssembliesPathSilverlight
        {
            get { return (string) dictionaryService.GetValue(PrismAssembliesPathSilverlightKey); }
            set
            {
                dictionaryService.SetValue(PrismAssembliesPathSilverlightKey, value);
                SetAssembliesExistenceFlag(PrismAssembliesSilverlight, PrismAssembliesPathSilverlight);
                OnPropertyChanged(PrismAssembliesPathSilverlightKey);
            }
        }

        private void SetAssembliesExistenceFlag(IEnumerable<AssemblyItem> coll, string path)
        {
            foreach (var assemblyItem in coll)
            {
                assemblyItem.Exists = fileSystemService.FileExists(Path.Combine(path, assemblyItem.Name));
            }
        }

        private void FillAssembliesInfoCollection(ObservableCollection<AssemblyItem> coll, string assembliesKey)
        {
            var assembliesString = (string) dictionaryService.GetValue(assembliesKey);
            if (!string.IsNullOrEmpty(assembliesString))
            {
                var assembliesArray = assembliesString.Split(';');
                foreach (var assemblyName in assembliesArray)
                {
                    coll.Add(new AssemblyItem {Name = assemblyName});
                }
            }
        }

        protected override void DoPropertyValidation(string propertyName, ref string error)
        {
            switch (propertyName)
            {
                case PrismAssembliesPathWpfKey:
                    if (!fileSystemService.PathExists(PrismAssembliesPathWpf))
                        error = Resources.InvalidPath;
                    break;
                case PrismAssembliesPathSilverlightKey:
                    if (!fileSystemService.PathExists(PrismAssembliesPathSilverlight))
                        error = Resources.InvalidPath;
                    break;
            }
        }

        protected override bool DoGlobalValidation(ref string error)
        {
            if (PrismAssembliesWpf != null && PrismAssembliesWpf.Any(assemblyItem => !assemblyItem.Exists))
            {
                error = Resources.InvalidFileFullName;
                return false;
            }
            if (PrismAssembliesSilverlight != null && PrismAssembliesSilverlight.Any(assemblyItem => !assemblyItem.Exists))
            {
                error = Resources.InvalidFileFullName;
                return false;
            }
            return base.DoGlobalValidation(ref error);
        }
    }
}